package componentes.obstaculo;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import componentes.Atacante;
import componentes.ElementoUbicableEnTerreno;
import componentes.Posicion;
import componentes.enemigo.Enemigo;

public abstract class Obstaculo extends Atacante {
	
	private Collection enemigosYaAtacados;

	public Obstaculo(Posicion posicion) {
		super(posicion);
		this.enemigosYaAtacados = new HashSet();
	}
	
	protected void aplicarEfectoEnEnemigo(Enemigo enemigo){
		enemigo.disminuirVelocidad(getVelocidadADisminuir());
		enemigosYaAtacados.add(enemigo);
	}
	
	protected boolean estaEnMiAlcance(Enemigo enemigo){
		// abajo trato de decir que el obstaculo debe estar en la misma posicion que el enemigo
		//pero tengo dudas de la cantidad de posiciones q ocupa el obstaculo
		//return this.getPosicion().distanciaCon(enemigo.getPosicion()) == 0;
		return !enemigo.vuela() && this.getPosicion().equals(enemigo.getPosicion()) && !yaLoAtaque(enemigo);
	}
	
	private boolean yaLoAtaque(Enemigo enemigo){
		return enemigosYaAtacados.contains(enemigo);
	}
	
	protected abstract double getVelocidadADisminuir();
	
	@Override
	protected boolean atacaSoloAUnEnemigoCerca() {
		return false;
	}
	
	@Override
	protected String getElementName() {
		return "obstaculo";
	}
	
	@Override
	protected void fillXMLElement(Element element) {
		for (Object enemigoObject : enemigosYaAtacados){
			Enemigo enemigo = (Enemigo) enemigoObject;
			element.add(enemigo.toRefXML());
		}
	}
	
	public static Obstaculo recuperarDesdeXML(Element elementoObstaculo, Map mapaEnemigos){
		Obstaculo obstaculo = (Obstaculo) ElementoUbicableEnTerreno.recuperarDesdeXML(elementoObstaculo);
		Iterator it = elementoObstaculo.elements("enemigo").iterator();
		while (it.hasNext()){
			Element elementoRefEnemigo = (Element) it.next();
			Enemigo enemigoAAgregar = (Enemigo) mapaEnemigos.get(elementoRefEnemigo.attributeValue("ref"));
			obstaculo.enemigosYaAtacados.add(enemigoAAgregar);
		}
		
		return obstaculo;
	}
}
